package it.fuesi.signit;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextPaint;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity{

	private static final String TAG = "SignPictures";
	private static final int CAMERA_REQUEST_CODE = 1;
	private static final int GALLERY_REQUEST_CODE = 2;
	
	private Uri pictureUri;
	
	private ImageView mPreview;
	private TextView mHint;
	
	private CurrentSettings settings;
	
	private Bitmap mBitmap;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		settings = CurrentSettings.instance(this);
		mPreview = (ImageView)findViewById(R.id.preview);
		mHint = (TextView)findViewById(R.id.gallery_hint);
		
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		Log.d(TAG, "Resuming main activity...");
		
		if(settings.getCurrentImageUri() != null){
			this.pictureUri = settings.getCurrentImageUri();
			if(signBitmap())
				mHint.setVisibility(View.INVISIBLE);
			else
				mHint.setVisibility(View.VISIBLE);
		}else
			mHint.setVisibility(View.VISIBLE);
		
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		if(pictureUri != null){
			settings.setCurrentImageUri(pictureUri);
			settings.save();
		}
	}
	

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch(item.getItemId()){
			case R.id.action_take_picture:{
				takePicture(null);
			}
			break;
//			case R.id.action_load_picture:{
//				loadPicture(null);
//			}
//			break;
			case R.id.action_settings:{
				openSettings(null);
			}
			break;
			case R.id.action_save:{
				savePicture(null);
			}
			break;
			case R.id.action_share:{
				sharePicture(null);
			}
			break;
		}
		return true;
	}
	
	public void takePicture(View view){
		Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
		boolean cameraExists = intent.resolveActivity(getPackageManager()) != null;
		if(cameraExists){
			File photo = new File(Environment.getExternalStorageDirectory(),  "Pic.jpg");
		    pictureUri = Uri.fromFile(photo);
		    intent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri);
		    startActivityForResult(intent, CAMERA_REQUEST_CODE);
		}
	    
	}
	
	public void loadPicture(View view){
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
		intent.setType("image/*");
		startActivityForResult(
				Intent.createChooser(intent, "Select..."), GALLERY_REQUEST_CODE);
	}
	
	
	private int getPosition(){
		return settings.getPosition();
	}
	
	private float getXPosition(Bitmap bm, int margin){
		final int position = getPosition();
		
		if(position == CurrentSettings.POSITION_BOTTOM_LEFT || position == CurrentSettings.POSITION_TOP_LEFT)
			return 0 + margin;
		else if(position == CurrentSettings.POSITION_BOTTOM_CENTER || position == CurrentSettings.POSITION_TOP_CENTER)
			return bm.getWidth()/2;
		else
			return bm.getWidth() - margin;
		
	}
	
	private float getYPosition(Bitmap bm, int margin, float textSize){
		final int position = getPosition();
		if(position == CurrentSettings.POSITION_TOP_CENTER || position == CurrentSettings.POSITION_TOP_LEFT || position == CurrentSettings.POSITION_TOP_RIGHT)
			return 0 + textSize + margin;
		else
			return bm.getHeight() - margin;
	}
	
	private Align getTextAlign(){
		final int position = getPosition();
		if(position == CurrentSettings.POSITION_BOTTOM_LEFT || position == CurrentSettings.POSITION_TOP_LEFT)
			return Align.LEFT;
		else if(position == CurrentSettings.POSITION_BOTTOM_CENTER || position == CurrentSettings.POSITION_TOP_CENTER)
			return Align.CENTER;
		else
			return Align.RIGHT;
	}
	
	public void openSettings(View view){
		Intent intent = new Intent(this, SettingsActivity.class);
		startActivity(intent);
	}
	
	private boolean signBitmap(){
		
		settings.setCurrentImageUri(pictureUri);
		
        getContentResolver().notifyChange(pictureUri, null);
        try {
        	Log.d(TAG, "Picture Uri: " + pictureUri.toString());
        	
			InputStream stream = getContentResolver().openInputStream(pictureUri);

			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;

			BitmapFactory.decodeStream(stream, null, options);
			stream.close();

			int w = options.outWidth;
			int h = options.outHeight;
			Log.d(TAG, "Bitmap raw size:" + w + " x " + h);

			int displayW = getResources().getDisplayMetrics().widthPixels;
			int displayH = getResources().getDisplayMetrics().heightPixels;

			int sample = 1;

			while (w > displayW * sample || h > displayH * sample) {
				sample = sample * 2;
			}
			Log.d(TAG, "Sampling at " + sample);

			options.inJustDecodeBounds = false;
			options.inSampleSize = sample;

			stream = getContentResolver().openInputStream(pictureUri);
			Bitmap bm = BitmapFactory.decodeStream(stream, null, options);
			stream.close();
			if (mBitmap != null) {
				mBitmap.recycle();
			}
			
			mBitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),
					Bitmap.Config.ARGB_8888);
			
			Canvas c = new Canvas(mBitmap);
			c.drawBitmap(bm, 0, 0, null);
			TextPaint tp = new TextPaint();
			
			float textSize = getTextSize();
			tp.setTextSize(textSize);
			tp.setColor(getTextColor()); 
			tp.setTextAlign(getTextAlign());
			tp.setStrokeWidth(getStrokeWidth());
			tp.setStyle(Style.STROKE);
			tp.setTypeface(Typeface.create(getTypeFace(), getTypeFaceStyle()));
			
			final String signature = settings.getSignature() != null ? settings.getSignature() : getString(R.string.default_signature);
			
			final int margin = settings.getMargin();
			
			c.drawText(signature, getXPosition(bm, margin), getYPosition(bm, margin, textSize), tp);
	
			bm.recycle();
			
			mPreview.setImageBitmap(mBitmap);
			
			//mBitmap.recycle();
			settings.setImageSigned(true);
			
			return true;
			
        }catch(Exception e){
        	e.printStackTrace();
        	return false;
        }
        
	}
	
	private float getTextSize(){
		float textSize = 0;
		
		switch(settings.getSize()){
			case R.id.sizeSmall:{
				textSize = getResources().getDimension(R.dimen.signature_small);
			}
			break;
			case R.id.sizeMedium:{
				textSize = getResources().getDimension(R.dimen.signature_medium);
			}
			break;
			case R.id.sizeLarge:{
				textSize = getResources().getDimension(R.dimen.signature_large);
			}
			break;
		}
		
		return textSize;
	}
	
	private int getTextColor(){
		int r = settings.getColorR();
		int g = settings.getColorG();
		int b = settings.getColorB();
		
		return Color.argb(255, r, g, b);
	}
	
	private int getStrokeWidth(){
		return settings.getStroke();
	}
	
	private Typeface getTypeFace(){
		String[] fonts = getResources().getStringArray(R.array.settings_fonts);
		String typeFaceName = fonts[settings.getTypeFace()];
		if(typeFaceName.equals("DEFAULT_BOLD"))
			return Typeface.DEFAULT_BOLD;
		if(typeFaceName.equals("MONOSPACE"))
			return Typeface.MONOSPACE;
		if(typeFaceName.equals("SANS_SERIF"))
			return Typeface.SANS_SERIF;
		if(typeFaceName.equals("SERIF"))
			return Typeface.SERIF;
		
		return Typeface.DEFAULT;
	}
	
	private int getTypeFaceStyle(){
		String[] styles = getResources().getStringArray(R.array.settings_fonts_style);
		String styleName = styles[settings.getTypeFaceStyle()];
		if(styleName.equals("BOLD"))
			return Typeface.BOLD;
		if(styleName.equals("ITALIC"))
			return Typeface.ITALIC;
		if(styleName.equals("BOLD_ITALIC"))
			return Typeface.BOLD_ITALIC;
		
		return Typeface.NORMAL;
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if(resultCode != RESULT_OK) {
			pictureUri = settings.getCurrentImageUri();
			return;	
		}
		
		settings.setImageSigned(false);
		
	    switch (requestCode) {
		    case CAMERA_REQUEST_CODE:{
		    	signBitmap();
		    }
		    break;
		    case GALLERY_REQUEST_CODE:{
		    	pictureUri = data.getData();
		    	signBitmap();
		    }
		    break;
	    }
	}
	
	
	private Uri savedPictureUri = null;
	
	public void savePicture(View v){
		if (mBitmap == null) {
			return;
		}
		
		File path = Environment
				.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
		Log.d(TAG, "Save path = " + path);
		path.mkdirs();

		String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
				.format(new Date());

		String filename = getString(R.string.app_name) +"_" + timestamp + ".jpg";
		File file = new File(path, filename);
		FileOutputStream stream;
		try {
			stream = new FileOutputStream(file);
			mBitmap.compress(CompressFormat.JPEG, 100, stream);
			stream.close();
		} catch (Exception e) {
			Log.e(TAG, "Save (compressing):", e);
			return; // Do not continue
		}
		
		savedPictureUri = Uri.fromFile(file);
		
		Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		intent.setData(savedPictureUri);
		
		sendBroadcast(intent);
		
		Toast.makeText(this, "Signed picture saved in " +file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
		
	}
	
	public void sharePicture(View v){
		if(savedPictureUri == null)
			savePicture(v);
		// Send the public picture file to my friend... 
		Intent share = new Intent(Intent.ACTION_SEND);
		share.setType("image/jpeg");
		share.putExtra(Intent.EXTRA_STREAM, savedPictureUri);
		startActivity(Intent.createChooser(share, "Share using..."));
	}
	
}
